home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_052
/
tek4010
/
remote.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
12KB
|
512 lines
/*
.index remote.c
*/
/****************************************************
* vt100 emulator - remote character interpretation
*
* Oct 86 TAW - added tek 4010 emulation and did some
* - minor bug fixes, I use Move/Draw instead of
* - RectFill, added the box to the extened character
* set
* 860823 DBW - Integrated and rewrote lots of code
* v2.0 860803 DRB - Rewrote the control sequence parser
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
****************************************************/
#include "vt100.h"
static int p [10];
static int numpar;
static char escseq[40];
void doctrl ();
void doesc (); /* force correct denomination */
void doerase ();
void doindex ();
/*
.page.index doremote
*/
/************************************************
* function to handle remote characters
*************************************************/
void
doremote (c)
char c;
{
if (Tek (c))
return;
if (inesc >= 0)
{
doesc (c);
return;
}
if (inctrl >= 0)
{
doctrl (c);
return;
}
switch (c)
{
case 15:
alt = 0;
break;
case 14:
alt = 1;
break;
case '\t':
x += 64 - ((x-MINX) % 64);
break;
case 10: /* lf */
case 11:
case 12:
if (nlmode)
doindex ('E');
else
doindex ('D');
break;
case 13: /* cr */
if (!nlmode)
x = MINX;
break;
case 8: /* backspace */
x -= 8;
if (x < MINX)
x = MINX;
break;
case 7: /* bell */
DisplayBeep (NULL);
break;
case 27:
inesc = 0;
break;
default:
if (c < ' ' || c > '~')
return;
if (a[alt] && c > '`')
doalt (c);
else
emitbatch (1,&c);
} /* end of switch */
}/* end doremote */
/*
.page.index doesc
*/
void
doesc (c)
char c;
{
if (inesc < 0)
{
inesc = 0;
return;
}
if (c == 27 || c == 24)
{ inesc = -1;
return;
}
if (c < ' ' || c == 127) /* Ignore control chars */
return;
if (c < '0') /* Collect intermediates */
{
escseq [inesc++] = c;
return;
}
/* by process of elimination, we have a final character. Put it in
the buffer, and dispatch on the first character in the buffer */
escseq [inesc] = c;
inesc = -1; /* No longer collecting a sequence */
switch (escseq[0]) /* Dispatch on the first received */
{
case '[': /* Control sequence introducer */
numpar = 0; /* No parameters yet */
private = 0; /* Not a private sequence (yet?) */
badseq = 0; /* Good until proven bad */
p[0] = p[1] = 0; /* But default the first parameter */
inctrl = 0; /* We are in a control sequence */
return; /* All done for now ... */
case 'D': case 'E': case 'M': /* Some kind of index */
doindex (c); /* Do the index */
return; /* Return */
case '7': /* Save cursor position */
savx = x; savy = y; savmode = curmode; savalt = alt;
sa[0] = a[0]; sa[1] = a[1];
return;
case '8': /* Restore cursor position */
x = savx; y = savy; alt = savalt; curmode = savmode;
a[0] = sa[0]; a[1] = sa[1];
return;
case 'c': /* Reset */
top = MINY; bot = MAXY; savx = MINX; savy = MINY;
a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
emit(12);
inesc = -1;
return;
case '(': /* Change character set */
if (c == '0' || c == '2')
a[0] = 1;
else
a[0] = 0;
return;
case ')': /* Change the other character set */
if (c == '0' || c == '2')
a[1] = 1;
else
a[1] = 0;
return;
/* If we didn't match anything, we can just return, happy in the
* knowledge that we've at least eaten the whole sequence */
}/* end switch */
return;
}/* end doesc */
/*
.page.index doctrl
*/
void
doctrl (c)
char c;
{
int i;
if (c == 27 || c == 24)
{
inctrl = -1;
return;
}
if (c < ' ' || c == 127) /* Ignore control chars */
return;
/* First, look for some parameter characters. If the very first
* parameter character isn't a digit, then we have a private sequence */
if (c >= '0' && c < '@')
{
/* can't have parameters after intermediates */
if (inctrl > 0)
{
badseq++;
return;
}
switch (c)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
p[numpar] = p[numpar] * 10 + (c - '0');
return;
case ';':
p[++numpar] = 0; /* Start a new parameter */
return;
case '<': case '=': case '>': case '?': /* Can only mean private */
if (inctrl = 0) private = c; /* Only allowed BEFORE parameters */
return;
/* if we come here, it's a bad sequence */
}
badseq++; /* Flag the bad sequence */
}
if (c < '0') /* Intermediate character */
{
escseq[inctrl++] = c; /* Save the intermediate character */
return;
}
/* if we get here, we have the final character. Put it in the
escape sequence buffer, then dispatch the control sequence */
numpar++; /* Reflect the real number of parameters */
escseq[inctrl++] = c; /* Store the final character */
escseq[inctrl] = '\000'; /* Tie off the buffer */
inctrl = -1; /* End of the control sequence scan */
/* Don't know how to do any private sequences right now,
* so just punt them */
if (private != 0 || badseq != 0)
return;
switch (escseq[0]) /* Dispatch on first intermediate or final */
{
case 'A':
if (p[0]<=0)
p[0] = 1;
y -= 8*p[0];
if (y<top)
y = top;
return;
case 'B':
if (p[0]<=0)
p[0] = 1;
y += 8*p[0];
if (y>bot)
y = bot;
return;
case 'C':
if (p[0]<=0)
p[0] = 1;
x += 8*p[0];
if (x>MAXX)
x = MAXX;
return;
case 'D':
if (p[0]<=0)
p[0] = 1;
x -= 8*p[0];
if (x<MINX)
x = MINX;
return;
case 'H': case 'f': /* Cursor position */
if (p[0] <= 0)
p[0] = 1;
if (p[1] <= 0)
p[1] = 1;
y = (--p[0]*8)+MINY;
x = (--p[1]*8)+MINX;
if (y > MAXY)
y = MAXY;
if (x > MAXX)
x = MAXX;
if (y < MINY)
y = MINY;
if (x < MINX)
x = MINX;
return;
case 'r': /* Set scroll region */
if (p[0] <= 0)
p[0] = 1;
if (p[1] <= 0)
p[1] = p_lines;
top = (--p[0]*8)+MINY;
bot = (--p[1]*8)+MINY;
if (top < MINY)
top = MINY;
if (bot > MAXY)
bot = MAXY;
if (top > bot)
{
top = MINY;
bot = MAXY;
}
x = MINX;
y = MINY;
return;
case 'm': /* Set graphic rendition */
for (i=0; i<numpar; i++)
{
if (p[i] < 0)
p[i] = 0;
switch (p[i])
{
case 0:
curmode = 0;
break;
case 1:
case 5:
if (p_depth > 1)
curmode |= BOLD;
else
curmode |= REVERSE;
break;
case 4:
curmode |= UNDERLINE;
break;
default:
curmode |= REVERSE;
break;
}
}
return;
case 'K': /* Erase in line */
doerase ();
return;
case 'J': /* Erase in display */
if (p[0] < 0)
p[0] = 0;
SetAPen (mywindow->RPort,0L);
if (p[0] == 0)
{
if (y < MAXY)
RectFill (mywindow->RPort,
(long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
}
else if (p[0] == 1)
{
if (y > MINY)
RectFill (mywindow->RPort,
(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
}
else
RectFill (mywindow->RPort,
(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
SetAPen (mywindow->RPort,1L);
doerase ();
return;
case 'h': /* Set parameter */
if (p[0] == 20)
nlmode = 1;
return;
case 'l': /* Reset parameter */
if (p[0] == 20)
nlmode = 0;
return;
case 'x':
sendchar (27);
sendstring ("[3;1;8;64;64;1;0x");
return;
case 'n':
if (p[0] == 6) {
sendchar (27);
sprintf (escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
sendstring (escseq);
return;
}
sendchar (27);
sendstring ("[0n");
return;
case 'c':
sendchar (27);
sendstring ("[?1;0c");
return;
}
/* Don't know how to do this one, so punt it */
}/* end doctrl */
/*
.page.index doindex
*/
void
doindex (c)
char c;
{
if (c != 'M')
{
if (c == 'E')
x = MINX;
if (y > bot)
if (y < MAXY)
y += 8;
if (y == bot)
ScrollRaster (mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
(long)(MAXX+7),(long)(bot+1));
if (y < bot)
y += 8;
}
else
{
if (y < top)
if (y > MINY)
y -= 8;
if (y == top)
ScrollRaster (mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
(long)(MAXX+7),(long)(bot+1));
if (y > top)
y -= 8;
}
return;
}/* end doindex */
/*
.page.index doalt
*/
doalt (c)
char c;
{
int oldx, newx;
inesc = -1;
oldx = x; emit (' ');
newx = x;
x = oldx;
SetAPen (mywindow->RPort,1L);
switch (c)
{
case 'a':
c = 127;
emitbatch (1, &c);
break;
case 'j':
case 'm':
case 'v':
doline (4,-8,4,-4);
if (c=='j')
doline (0,-4,4,-4);
else if (c=='m')
doline (4,-4,8,-4);
else
doline (0,-4,8,-4);
break;
case 'k':
case 'l':
case 'w':
doline (4,-4,4,0);
if (c=='k')
doline(0,-4,4,-4);
else if (c=='l')
doline (4,-4,8,-4);
else
doline (0,-4,8,-4);
break;
case 'n':
case 'q':
doline (0,-4,8,-4);
if (c=='n')
doline (4,-8,4,0);
break;
case 't':
case 'u':
case 'x':
doline (4,-8,4,0);
if (c=='t')
doline (4,-4,8,-4);
else if (c=='u')
doline (0,-4,4,-4);
break;
}
x = newx;
}/* end doalt */
/*
.index doline
*/
doline (x1,y1,x2,y2)
{
Move (mywindow->RPort, x+x1, y+y1);
Draw (mywindow->RPort, x+x2, y+y2);
}
/*
.index doerase
*/
void doerase ()
{
if (p[0] < 0)
p[0] = 0;
SetAPen (mywindow->RPort,0L);
if (p[0] == 0)
RectFill (mywindow->RPort,(long)x,(long)(y-6),
(long)(MAXX+7),(long)(y+1));
else if (p[0] == 1)
RectFill (mywindow->RPort,
(long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
else
RectFill (mywindow->RPort,
(long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
SetAPen (mywindow->RPort,1L);
return;
}/* end doerase */